/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.tcmj.common.jdbc.connect.intern;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author tcmj
 */
public class PreparedStmtWatcher {

    /** slf4j Logging framework. */
    private static final transient Logger logger = LoggerFactory.getLogger(PreparedStmtWatcher.class);

    private Connection con;

    private Set<PreparedStatement> pstObjectSet;

    private int count_created;

    private int count_closed;

    private boolean debug = false;

    public PreparedStmtWatcher(Connection con) {
        this.con = con;
        this.pstObjectSet = new HashSet<PreparedStatement>();
        this.count_created = 0;
        this.count_closed = 0;
    }

    public PreparedStatement getPreparedStatement(String sql) throws SQLException {

        PreparedStatement pstmt = con.prepareStatement(sql);
        pstObjectSet.add(pstmt);
        count_created++;

        if (debug && pstmt != null) {
            logger.debug("creating an new PreparedStatement " + Integer.toHexString(pstmt.hashCode()));
        }
        return pstmt;

    }

    public PreparedStatement getPreparedStatement(String sql, int rsType,
            int rsConcurrency, int rsHoldability) throws SQLException {

        PreparedStatement pstmt = con.prepareStatement(sql, rsType, rsConcurrency, rsHoldability);
        pstObjectSet.add(pstmt);
        count_created++;

        if (debug && pstmt != null) {
            logger.debug("creating an new PreparedStatement " + Integer.toHexString(pstmt.hashCode()));
        }
        return pstmt;

    }

    public PreparedStatement getPreparedStatement(String sql, int autoGeneratedKeys) throws SQLException {

        PreparedStatement pstmt = con.prepareStatement(sql, autoGeneratedKeys);
        pstObjectSet.add(pstmt);
        count_created++;

        if (debug && pstmt != null) {
            logger.debug("creating an new AGK-PreparedStatement " + Integer.toHexString(pstmt.hashCode()));
        }
        return pstmt;

    }

    public PreparedStatement getPreparedStatement(String sql, int columnIndexes[]) throws SQLException {

        PreparedStatement pstmt = con.prepareStatement(sql, columnIndexes);
        pstObjectSet.add(pstmt);
        count_created++;

        if (debug && pstmt != null) {
            logger.debug("creating an new AGK[]-PreparedStatement " + Integer.toHexString(pstmt.hashCode()));
        }
        return pstmt;

    }

    public PreparedStatement getPreparedStatement(String sql, String columnNames[]) throws SQLException {

        PreparedStatement pstmt = con.prepareStatement(sql, columnNames);
        pstObjectSet.add(pstmt);
        count_created++;

        if (debug && pstmt != null) {
            logger.debug("creating an new AGK[]-PreparedStatement " + Integer.toHexString(pstmt.hashCode()));
        }
        return pstmt;

    }

    public void closePreparedStatement(PreparedStatement statement) throws SQLException {
        logger.debug("closing PreparedStatement " + statement);
        pstObjectSet.remove(statement);
        statement.close();
        count_closed++;
    }

    public void closeall() {

        for (PreparedStatement prepStmt : pstObjectSet) {

            try {
//                    if (!prepStmt.isClosed()) {
                if (debug) {
                    logger.debug("closing PreparedStatement " + prepStmt);
                }
                prepStmt.close();
                count_closed++;
//                    }
            } catch (Exception e) {
                if (debug) {
                    logger.debug("error closing PreparedStatement " +
                            prepStmt + ": " + e.getMessage());
                }
            }

        }
//        pstObjectSet.clear();

    }

    /**
     * Getter for property debug.
     * @return Value of property debug.
     */
    public boolean isDebug() {
        return debug;
    }

    /**
     * Setter for property debug.
     * @param debug New value of property debug.
     */
    public void setDebug(boolean debug) {
        this.debug = debug;
    }

    public int getCountCreated() {
        return this.count_created;
    }

    public int getCountClosed() {
        return this.count_closed;
    }

    public String getCloseInfo() {
        return "closed: " + count_closed + "/" + count_created;
    }

    @Override
    public String toString() {
        return "PstStmtWatcher@" + Integer.toHexString(hashCode());
    }

}
